home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 11255 / 11255.xpi / chrome / content / controller / Toolbar.js < prev    next >
Text File  |  2010-02-10  |  47KB  |  1,261 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * 
  3.  * Pearltrees add-on AMO, Copyright(C), 2009, Broceliand SAS, Paris, France 
  4.  * (company in charge of developing Pearltrees)
  5.  * 
  6.  * This file is part of ΓÇ£Pearltrees add-on AMOΓÇ¥.  
  7.  * 
  8.  * Pearltrees add-on AMO is free software: you can redistribute it and/or modify it under the 
  9.  * terms of the GNU General Public License version 3 as published by the Free Software Foundation.
  10.  * 
  11.  * Pearltrees add-on AMO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
  12.  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
  13.  * See the GNU General Public License for more details.
  14.  * 
  15.  * You should have received a copy of the GNU General Public License along with Pearltrees add-on AMO. 
  16.  * If not, see <http://www.gnu.org/licenses/>
  17.  * 
  18.  * ***** END LICENSE BLOCK ***** */
  19.  
  20. /////////////////////////////////////////////////////////////////////////////////
  21. // Global actions
  22. /////////////////////////////////////////////////////////////////////////////////
  23.  
  24. const RECORING_MODE_ONE_BY_ONE = 1;
  25. const RECORING_MODE_CONTINUOUS = 2;
  26. const DEFAULT_RECORDING_MODE = RECORING_MODE_ONE_BY_ONE;
  27.  
  28. const SYNC_TREE_SELECTION_WITH_FLEX = false;
  29. const PERSIST_RECORDING_MODE = false;
  30.  
  31. const URL_RECORDED_BEFORE_ALERT = 25;
  32. const ALERT_STEP_1 = 25;
  33. const ALERT_STEP_2 = 50;
  34. const ALERT_STEP_3 = 75;
  35. const MAX_PEARLS_IN_TREE = 100;
  36.  
  37. /**
  38.  * Global variables like recording state or visibility.
  39.  */ 
  40. var BRO_toolbar = { 
  41.  
  42.     isOnline:false, 
  43.     isRecording:false, 
  44.     isHidden:true, 
  45.     isRevealed:true,
  46.     isFirstInstallMode:false, 
  47.     isUpdate:false,
  48.     isUserLogged:false,
  49.     recordingMode: DEFAULT_RECORDING_MODE,
  50.     lastUrlRecorded:null,
  51.     isInit:false,
  52.     showHelpOnRecording:false,
  53.     helpStartupWindow:null,
  54.     nameMapWindow:null,
  55.     manyPearlsWindow:null,
  56.     optionWindow:null,
  57.     initTime:null,
  58.     viewLoaded:false, 
  59.     
  60.     init: function() {      
  61.         BRO_toolbar.isInit = true;
  62.         
  63.         // Log
  64.         BRO_log.init();
  65.         var d = new Date();
  66.         BRO_toolbar.initTime = d.getTime();
  67.         BRO_log.log("initializing");
  68.         
  69.         // Local
  70.         BRO_locale.init();        
  71.         
  72.         BRO_toolbar.validateEnv();
  73.         
  74.         // Model
  75.         BRO_model.init();      
  76.         BRO_windowManager.init();
  77.          
  78.         // Listeners
  79.         BRO_browserManager.init();
  80.         BRO_actionListener.init();
  81.         BRO_listenerHandler.init();
  82.         // Download listener is disabled
  83.         //BRO_downloadListener.init();
  84.         BRO_extensionManagerListener.init();
  85.         BRO_toolbar.initFlexCommandListener();
  86.         
  87.         window.addEventListener("online", BRO_toolbar.onOnline, false);
  88.         window.addEventListener("offline", BRO_toolbar.onOffline, false);
  89.         
  90.         // Detect installation / updates and load user stats
  91.         BRO_toolbar.loadPreferences();
  92.  
  93.         // UI
  94.         BRO_ButtonsHandler.init(this.recordingMode);    
  95.     },
  96.     
  97.     onUninstall:function() {
  98.         BRO_log.log("Uninstalling");
  99.         
  100.         BRO_toolbar.resetPreferences();
  101.         BRO_ButtonsHandler.removeAllButtons();
  102.     },
  103.     
  104.     onFirstInstall:function() {
  105.         BRO_log.log("Installing");
  106.         BRO_toolbar.isFirstInstall = true;
  107.         BRO_model.clear();
  108.  
  109.         if(BRO_toolbar.viewLoaded) {
  110.             BRO_ButtonsHandler.addFirstInstallButtonInNavBar();
  111.             BRO_model.getTreesAndCurrentUser(skipNotificationIfNotLogged = true);
  112.         }
  113.     },
  114.     
  115.     onUpdate:function() {
  116.         BRO_log.log("Updating");
  117.         BRO_toolbar.isUpdate = true;
  118.         BRO_model.clear();
  119.  
  120.         if(BRO_toolbar.viewLoaded && BRO_ButtonsHandler.restoreDefaultPostionOnLoad) {
  121.             BRO_ButtonsHandler.restoreDefaultPositionInNavbar();
  122.             BRO_ButtonsHandler.restoreDefaultPostionOnLoad = false;
  123.             BRO_model.getTreesAndCurrentUser(skipNotificationIfNotLogged = true);
  124.         }
  125.     },
  126.     
  127.     onDownloadNotifiedToAMO:function() {
  128.         var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  129.                                        .getService(Components.interfaces.nsIPrefService)
  130.                                        .getBranch("extensions.bro_toolbar.");   
  131.         
  132.         prefs.setBoolPref("amo_dl_notified", true);
  133.         
  134.         BRO_log.log("AMO notified of download");        
  135.     },
  136.     
  137.     onActiveUserNotifiedToAMO:function() {
  138.         var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  139.                                        .getService(Components.interfaces.nsIPrefService)
  140.                                        .getBranch("extensions.bro_toolbar.");   
  141.         
  142.         prefs.setCharPref("amo_active_date", BRO_toolbar.formatCurrentDayDate());        
  143.         
  144.         BRO_log.log("AMO notified of being active");
  145.     },
  146.     
  147.     formatCurrentDayDate:function() {
  148.         var date = new Date();
  149.         return date.getFullYear()+""+(date.getMonth()+1)+""+date.getDate();
  150.     },
  151.     
  152.     isThirdPartyCookiesEnabled:function() {
  153.         var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  154.                    .getService(Components.interfaces.nsIPrefService)
  155.                    .getBranch("network.cookie.");
  156.         var cookieBehavior = prefs.getIntPref("cookieBehavior");
  157.         
  158.         return (cookieBehavior == 0)?true:false;
  159.     },
  160.     
  161.     enableThirdPartyCookies:function() {
  162.         var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  163.                    .getService(Components.interfaces.nsIPrefService)
  164.                    .getBranch("network.cookie.");
  165.         prefs.setIntPref("cookieBehavior", 0);        
  166.     },
  167.     
  168.     /**
  169.      * @todo create a custom dialog in order to remove the default image:
  170.      * @see https://developer.mozilla.org/en/Code_snippets/Dialogs_and_Prompts
  171.      * 
  172.      * @return boolean
  173.      */
  174.     isUserWantToEnableThirdPartyCookies:function() {
  175.         var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
  176.                                 .getService(Components.interfaces.nsIPromptService);
  177.         return prompts.confirm(window, "", BRO_locale.getString('cookiesError.text'));      
  178.     },
  179.     
  180.     resetPreferences:function() {      
  181.         var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  182.                                        .getService(Components.interfaces.nsIPrefService)
  183.                                        .getBranch("extensions.bro_toolbar.");
  184.         prefs.setBoolPref("firstrun", true);        
  185.         prefs.setBoolPref("firstuse", true);        
  186.         prefs.setBoolPref("isFirstInstallMode", true);
  187.         prefs.setBoolPref("amo_dl_notified", false);
  188.         prefs.setCharPref("amo_active_date", "");
  189.         prefs.setCharPref("version", "");
  190.         prefs.setCharPref("currentUser", "");
  191.         prefs.setCharPref("rootTree", ""); 
  192.         prefs.setCharPref("dropZone", ""); 
  193.         prefs.setIntPref("recordingMode", DEFAULT_RECORDING_MODE);
  194.     },
  195.     
  196.     loadPreferences:function() {
  197.         var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  198.                    .getService(Components.interfaces.nsIPrefService)
  199.                    .getBranch("extensions.bro_toolbar.");
  200.  
  201.         var ver = -1;
  202.         var firstrun = true;
  203.         var firstuse = true;
  204.         var isFirstInstallMode = true;
  205.         var amoDownloadNotified = false;
  206.         var amoLastActiveDate = "";
  207.         var currentUser = null;
  208.         this.showHelpOnRecording = false;
  209.         
  210.         var gExtensionManager = Components.classes["@mozilla.org/extensions/manager;1"]
  211.                                 .getService(Components.interfaces.nsIExtensionManager);
  212.         var current = gExtensionManager.getItemForID(BRO_ADDON_ID).version;
  213.             
  214.         try {
  215.             ver = prefs.getCharPref("version");
  216.             firstrun = prefs.getBoolPref("firstrun");
  217.             firstuse = prefs.getBoolPref("firstuse"); 
  218.             isFirstInstallMode = prefs.getBoolPref("isFirstInstallMode");
  219.             amoDownloadNotified = prefs.getBoolPref("amo_dl_notified");
  220.             amoLastActiveDate = prefs.getCharPref("amo_active_date");
  221.         }catch(e){
  222.             //nothing
  223.         }finally {
  224.             // if it is the first pearlbar installation
  225.             if (firstrun) {
  226.                 prefs.setBoolPref("firstrun", false);
  227.                 firstuse = true;
  228.                 prefs.setBoolPref("firstuse", firstuse);
  229.                 isFirstInstallMode = true;
  230.                 prefs.setBoolPref("isFirstInstallMode", true);
  231.                 prefs.setCharPref("version",current);
  232.         
  233.                 BRO_toolbar.onFirstInstall();
  234.             }
  235.             // if this is a pearlbar update
  236.             else if (ver!=current) {
  237.                 var versionChecker = Components.classes["@mozilla.org/xpcom/version-comparator;1"]
  238.                                                .getService(Components.interfaces.nsIVersionComparator);                
  239.                 if(versionChecker.compare(ver, "5.0") < 0) {
  240.                     BRO_ButtonsHandler.restoreDefaultPostionOnLoad = true;
  241.                     firstuse = true;
  242.                     prefs.setBoolPref("firstuse", firstuse);                    
  243.                 }
  244.                 prefs.setCharPref("version", current);
  245.             
  246.                 BRO_toolbar.onUpdate();                
  247.                 this.showHelpOnRecording = true;
  248.             }
  249.             this.isFirstInstallMode = isFirstInstallMode;
  250.             this.showHelpOnRecording = firstuse;
  251.             if(PERSIST_RECORDING_MODE) {
  252.                 this.recordingMode = this.backupRecordingModeFromPreferences();
  253.             }
  254.             
  255.             if(BRO_ADDON_SOURCE == BRO_ADDON_SOURCE_SELFHOSTED) {
  256.                 if(!amoDownloadNotified) {
  257.                     BRO_model.notifyDownloadToAMO();
  258.                 }
  259.                 if(amoLastActiveDate != BRO_toolbar.formatCurrentDayDate()) {
  260.                     BRO_model.notifyActiveUserToAMO();
  261.                 }
  262.             }
  263.             
  264.             BRO_model.updateCurrentUser(this.backupCurrentUserFromPreferences());
  265.         }
  266.     },
  267.     
  268.     backupCurrentUserFromPreferences:function() {
  269.         var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  270.                                        .getService(Components.interfaces.nsIPrefService)
  271.                                        .getBranch("extensions.bro_toolbar.");
  272.         
  273.         var currentUser = null;
  274.         try{
  275.             currentUser = prefs.getCharPref("currentUser");
  276.         }catch(e){}
  277.         return (currentUser && currentUser != '')?BRO_model._json.decode(currentUser):null;        
  278.     },
  279.     
  280.     saveCurrentUserIntoPreferences:function(currentUser) {
  281.         var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  282.                                        .getService(Components.interfaces.nsIPrefService)
  283.                                        .getBranch("extensions.bro_toolbar.");
  284.         
  285.         var encodedUser = (currentUser)?BRO_model._json.encode(currentUser):'';
  286.         prefs.setCharPref("currentUser", encodedUser);        
  287.     },
  288.     
  289.     backupRootTreeFromPreferences:function() {
  290.         var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  291.                                        .getService(Components.interfaces.nsIPrefService)
  292.                                        .getBranch("extensions.bro_toolbar.");
  293.         
  294.         var rootTree = null;
  295.         try{
  296.             rootTree = prefs.getCharPref("rootTree");
  297.         }catch(e){}
  298.         return (rootTree && rootTree != '')?BRO_model._json.decode(rootTree):null;        
  299.     },
  300.     
  301.     saveRootTreeIntoPreferences:function(rootTree) {
  302.         var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  303.                                        .getService(Components.interfaces.nsIPrefService)
  304.                                        .getBranch("extensions.bro_toolbar.");
  305.         
  306.         var encodedRootTree = (rootTree)?BRO_model._json.encode(rootTree):'';
  307.         prefs.setCharPref("rootTree", encodedRootTree);        
  308.     },
  309.     
  310.     backupDropZoneFromPreferences:function() {
  311.         var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  312.                                        .getService(Components.interfaces.nsIPrefService)
  313.                                        .getBranch("extensions.bro_toolbar.");
  314.         
  315.         var dropZone = null;
  316.         try{
  317.             dropZone = prefs.getCharPref("dropZone");
  318.         }catch(e){}
  319.         return (dropZone && dropZone != '')?BRO_model._json.decode(dropZone):null;        
  320.     },
  321.     
  322.     saveDropZoneIntoPreferences:function(dropZone) {
  323.         var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  324.                                        .getService(Components.interfaces.nsIPrefService)
  325.                                        .getBranch("extensions.bro_toolbar.");
  326.         
  327.         var encodedDropZone = (dropZone)?BRO_model._json.encode(dropZone):'';
  328.         prefs.setCharPref("dropZone", encodedDropZone);        
  329.     },        
  330.     
  331.     backupRecordingModeFromPreferences:function() {
  332.         var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  333.                                        .getService(Components.interfaces.nsIPrefService)
  334.                                        .getBranch("extensions.bro_toolbar.");
  335.         
  336.         var recordingMode = DEFAULT_RECORDING_MODE;        
  337.         try{
  338.             recordingMode = prefs.getIntPref("recordingMode");            
  339.         }catch(e){
  340.             //nothing
  341.         }
  342.         finally{        
  343.             if(recordingMode != RECORING_MODE_ONE_BY_ONE && recordingMode != RECORING_MODE_CONTINUOUS) {
  344.                 recordingMode = DEFAULT_RECORDING_MODE;
  345.             }              
  346.             return recordingMode;
  347.         }       
  348.     },
  349.      
  350.     saveRecordingModeIntoPreferences:function(recordingMode) {
  351.         if(recordingMode != RECORING_MODE_ONE_BY_ONE && recordingMode != RECORING_MODE_CONTINUOUS) {
  352.             return;
  353.         }
  354.            var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  355.                                           .getService(Components.interfaces.nsIPrefService)
  356.                                           .getBranch("extensions.bro_toolbar.");
  357.            
  358.            prefs.setIntPref("recordingMode", recordingMode);
  359.     },    
  360.  
  361.     setFirstUse:function(value) {
  362.         var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  363.                                        .getService(Components.interfaces.nsIPrefService)
  364.                                        .getBranch("extensions.bro_toolbar.");
  365.         
  366.         prefs.setBoolPref("firstuse",value);
  367.         this.showHelpOnRecording = value;
  368.     },
  369.     
  370.     setFirstInstallMode:function(value) {
  371.         if(this.isFirstInstallMode && !value) {
  372.             BRO_ButtonsHandler.restoreDefaultPositionInNavbar();
  373.             // There is a bug while calculating the button width at this time
  374. //            BRO_ButtonsHandler.onButtonsCreated();
  375.             BRO_recordButtonController.refreshModeSelection();
  376.             BRO_inButtonController.refreshTreeListVisualComponents();
  377.         }
  378.         this.isFirstInstallMode = value;
  379.         
  380.         var prefs = Components.classes["@mozilla.org/preferences-service;1"]
  381.                                        .getService(Components.interfaces.nsIPrefService)
  382.                                        .getBranch("extensions.bro_toolbar.");
  383.         
  384.         prefs.setBoolPref("isFirstInstallMode", value);
  385.     },
  386.      
  387.     onQuit:function() {
  388.         BRO_model.clear();
  389.     },
  390.     
  391.     addUrlRecorded:function(url) {
  392.         BRO_toolbar.lastUrlRecorded = url;
  393.         BRO_noteController.init();
  394.         BRO_toolbar.addPearlCountToSelection();
  395.         BRO_toolbar.addUrlRecordedCountToSelection();
  396.  
  397.         var pearlCount = this.getSelectionPearlCount();
  398.         var urlRecordedCount = this.getSelectionUrlRecordedCount();
  399.         var isDropZoneSelected = BRO_inButtonController.isDropZoneSelected();
  400.         
  401.         if((pearlCount == ALERT_STEP_1 || pearlCount == ALERT_STEP_2 || pearlCount == ALERT_STEP_3) 
  402.          && urlRecordedCount >= URL_RECORDED_BEFORE_ALERT
  403.          && !isDropZoneSelected
  404.          && this.recordingMode == RECORING_MODE_CONTINUOUS) {
  405.             
  406.             BRO_toolbar.setRecordingMode(RECORING_MODE_ONE_BY_ONE);
  407.             
  408.             BRO_log.log("Alert. Current tree has "+pearlCount+ " pearls");
  409.             BRO_tools.callWithDelay('BRO_toolbar.showManyPearlsWindow()', BRO_buttonEffectHelper.START_RECORDING_EFFECT_TIME);
  410.         }
  411.     },
  412.     
  413.     isCurrentTreeFull:function() {
  414.         var pearlCount = this.getSelectionPearlCount();
  415.         var isDropZoneSelected = BRO_inButtonController.isDropZoneSelected();
  416.  
  417.         if(pearlCount >= MAX_PEARLS_IN_TREE && !isDropZoneSelected) {             
  418.             BRO_toolbar.showTreeFullWindow();
  419.             return true;
  420.         }
  421.         
  422.         return false;
  423.     },
  424.     
  425.     getSelectedItem:function() {
  426.         if(BRO_inButtonController.getSelectedTree()) {           
  427.             return BRO_inButtonController.getSelectedTree();
  428.         }
  429.         else if(BRO_inButtonController.getSelectedHistory()){            
  430.             return BRO_inButtonController.getSelectedHistory();
  431.         }
  432.         else if(BRO_inButtonController.getSelectedNewHistory()) {            
  433.             return BRO_inButtonController.getSelectedNewHistory();
  434.         }
  435.         else{
  436.             return null;
  437.         }
  438.     },
  439.     
  440.     addPearlCountToSelection:function() {
  441.         if(!this.getSelectedItem()) return;
  442.         
  443.         var pearlCount = this.getSelectionPearlCount();        
  444.         this.getSelectedItem().pearlCount = pearlCount + 1;    
  445.     },
  446.  
  447.     addUrlRecordedCountToSelection:function() {
  448.         if(!this.getSelectedItem()) return;
  449.         
  450.         var urlRecordedCount = this.getSelectionUrlRecordedCount();        
  451.         this.getSelectedItem().urlRecordedCount = urlRecordedCount + 1;     
  452.     },
  453.     
  454.     getSelectionPearlCount:function() {
  455.         var selectedItem = this.getSelectedItem();
  456.         if(!selectedItem) return 0;
  457.  
  458.         var pearlCount = parseInt(selectedItem.pearlCount);            
  459.         if(isNaN(pearlCount)) {
  460.             return 0;
  461.         }else{
  462.             return pearlCount;
  463.         }
  464.     }, 
  465.     
  466.     getSelectionUrlRecordedCount:function() {
  467.         var selectedItem = this.getSelectedItem();       
  468.         if(!selectedItem) return 0;
  469.  
  470.         var urlRecordedCount = parseInt(selectedItem.urlRecordedCount);            
  471.         if(isNaN(urlRecordedCount)) {
  472.             return 0;
  473.         }else{
  474.             return urlRecordedCount;
  475.         }       
  476.     },
  477.      
  478.     isCurrentUrlRecorded:function() {
  479.         return (this.lastUrlRecorded == BRO_browserManager.getSelectedBrowserUrl());
  480.     },
  481.     
  482.     getRecordingMode:function() {
  483.         return this.recordingMode;
  484.     },
  485.     
  486.     setRecordingMode:function(value) {
  487.         if(this.recordingMode != RECORING_MODE_ONE_BY_ONE && this.recordingMode != RECORING_MODE_CONTINUOUS) {
  488.             return;
  489.         }
  490.         if(this.recordingMode == value) {
  491.             return;
  492.         }
  493.         
  494.         this.recordingMode = value;
  495.         if(PERSIST_RECORDING_MODE) {
  496.             this.saveRecordingModeIntoPreferences(this.recordingMode);
  497.         }
  498.         
  499.         // oneByOne mode
  500.         if(this.recordingMode == RECORING_MODE_ONE_BY_ONE) {
  501.             // stop recording
  502.             if(this.isRecording) {
  503.                 this.setRecording(false);
  504.             }
  505.             this.lastUrlRecorded = null;
  506.         }
  507.         
  508.         // continuous mode
  509.         if(this.recordingMode == RECORING_MODE_CONTINUOUS) {
  510.             var currentUser = BRO_model.getCurrentUser();
  511.             var selectedTree = BRO_inButtonController.getSelectedTree();
  512.             if(selectedTree) {
  513.                 var selectedTreeId = selectedTree.treeID;
  514.             }
  515.             if(currentUser) {
  516.                 var dropZoneID = currentUser.dropZoneID;
  517.             }
  518.             // start recording
  519.             if(!this.isRecording) {
  520.                 this.setRecording(true);
  521.                 if(!this.isCurrentUrlRecorded()) {
  522.                     BRO_ButtonsHandler.recordCurrentPage();
  523.                 }
  524.             }
  525.         }
  526.         BRO_recordButtonController.refreshModeSelection();
  527.         BRO_windowManager.setRecordingMode(value);
  528.     },
  529.     
  530.     setRecording:function(value) {
  531.         if(this.isRecording == value) return;
  532.         
  533.         this.isRecording = value;                
  534.         BRO_windowManager.setRecording(value);
  535.         
  536.         if(value) {            
  537.             // Visually start recording
  538.             BRO_ButtonsHandler.startRecording();
  539.             // Start browser listeners
  540.             BRO_listenerHandler.registerListeners();
  541.             // Refresh list if just revealed
  542.             if(BRO_toolbar.isRevealed) {
  543.                 BRO_model.getTreesAndCurrentUser();
  544.             }
  545.             // A reveal will be needed
  546.             BRO_toolbar.isRevealed = false;
  547.             
  548.             if(this.showHelpOnRecording) {
  549.                 BRO_toolbar.showHelpRecording();
  550.                 this.setFirstUse(false);
  551.             }
  552.         }else {
  553.             // Reset recording infos
  554.             if(this.recordingMode == RECORING_MODE_CONTINUOUS) {               
  555.                 BRO_toolbar.lastUrlRecorded = null;  
  556.             }
  557.             // Remove listeners
  558.             BRO_listenerHandler.unregisterListeners();            
  559.             // Visually stop recording
  560.             BRO_ButtonsHandler.stopRecording();
  561.         }
  562.     },
  563.     
  564.     treeSelectionChanged:function() {
  565.         if(this.recordingMode == RECORING_MODE_ONE_BY_ONE) {
  566.             if(!BRO_toolbar.isCurrentUrlRecorded()) {
  567.                 BRO_toolbar.lastUrlRecorded = null;
  568.             }
  569.         }
  570.     },
  571.     
  572.     openCreateAccountPage:function() {
  573.         BRO_tools.openURLinCurrentTab(BRO_SERVICE_FF_URL+"createAccount");
  574.     },
  575.  
  576.     openLoginPage:function() {
  577.         BRO_tools.openURLinCurrentTab(BRO_SERVICE_FF_URL+"login");
  578.     },
  579.     
  580.     reveal:function() {
  581.         if(this.isRecording) {
  582.             BRO_toolbar.setRecording(false);
  583.         }
  584.         BRO_buttonEffectHelper.runRevealEffect();
  585.         BRO_toolbar.lastUrlRecorded = null;
  586.         BRO_toolbar.setRecordingMode(RECORING_MODE_ONE_BY_ONE);
  587.         
  588.         var revealDelay = BRO_buttonEffectHelper.REVEAL_EFFECT_TIME + 100;
  589.         
  590.         // If there is a selected tree we reveal into this tree
  591.         if(BRO_inButtonController.getSelectedTree()) {
  592.             var currentUser = BRO_model.getCurrentUser();
  593.             if(currentUser) {
  594.                 var isOnPearltrees = this.isPearltreesPublicUrl();
  595.                 var selectedTreeId = BRO_inButtonController.getSelectedTree().treeID;
  596.                 var flexSelectedTreeID = this.getFlexSelectedTreeIdFromAnchorParams();
  597.                 if(isOnPearltrees && selectedTreeId == flexSelectedTreeID) {
  598.                     gBrowser.reload();
  599.                 }else{                  
  600.                     this.openSelectedTreeInCurrentTab(revealDelay);
  601.                 }
  602.             }else{
  603.                 BRO_tools.openURLinCurrentTab(BRO_PUBLIC_URL+"/#", revealDelay);
  604.             }
  605.         }
  606.         // Else we reveal the current history
  607.         else{
  608.             BRO_tools.openURLinCurrentTab(BRO_SERVICE_FF_URL+"reveal", revealDelay);
  609.         }
  610.         
  611.         BRO_toolbar.isRevealed = true;
  612.     },
  613.     
  614.     openSelectedTreeInCurrentTab:function(delay, focusIfSelected) {       
  615.         var currentUser = BRO_model.getCurrentUser();
  616.         var selectedTree = BRO_inButtonController.getSelectedTree();
  617.         if(!selectedTree || !currentUser) {           
  618.             return;
  619.         }        
  620.         
  621.         var selectedTreeId = selectedTree.treeID;
  622.         var isOnPearltrees = this.isPearltreesPublicUrl();
  623.         var isDropZoneSelected = (selectedTreeId == currentUser.dropZoneID);
  624.         
  625.         if(isOnPearltrees) {
  626.             var flexSelectedTreeID = this.getFlexSelectedTreeIdFromAnchorParams();
  627.             var flexFocusedTreeID = this.getFlexFocusedTreeIdFromAnchorParams();
  628.             var isAlreadySelected = (selectedTreeId == flexSelectedTreeID);
  629.             var isAlreadyFocused = (selectedTreeId == flexFocusedTreeID);
  630.             if(isDropZoneSelected || (isAlreadySelected && !focusIfSelected) || isAlreadyFocused) {            
  631.                 return;
  632.             }
  633.         }
  634.         else if(!isOnPearltrees && isDropZoneSelected) {
  635.             selectedTreeId = currentUser.rootTreeID;
  636.         }
  637.             
  638.         var flexUrl = BRO_toolbar.getCurrentPearltreesPublicUrl();
  639.         flexUrl += "#N-u="+currentUser.userDB+"_"+currentUser.userID;
  640.         flexUrl += "&N-f="+currentUser.userDB+"_"+selectedTreeId;
  641.         flexUrl += "&N-s="+currentUser.userDB+"_"+selectedTreeId;
  642.         
  643.         BRO_log.log('navigate to: '+flexUrl); 
  644.         
  645.         BRO_tools.openURLinCurrentTab(flexUrl, delay);       
  646.     },
  647.     
  648.     onUseToolbar:function() {
  649.         BRO_buttonEffectHelper.stopHelpEffects();
  650.     },
  651.     
  652.     onLocationChange:function(url) {
  653.         // Is on pearltrees
  654.         if(this.isPearltreesPublicUrl()) {           
  655.             var params = this.getCurrentUrlAnchorParams();
  656.             
  657.             // Run & stop samba effect
  658.             if(params['Pearlbar-samba']=='1'){
  659.                 BRO_buttonEffectHelper.runHelpEffects();
  660.             }
  661.             else {
  662.                 BRO_buttonEffectHelper.stopHelpEffects();
  663.             }
  664.             
  665.             // Sync with Flex navigation
  666.             if(SYNC_TREE_SELECTION_WITH_FLEX) {
  667.                 var flexSelectedUserID = this.getFlexSelectedUserIdFromAnchorParams();
  668.                 var currentUser = BRO_model.getCurrentUser();
  669.                 var currentUserID = (currentUser)?currentUser.userID:null;
  670.                 if(flexSelectedUserID && currentUserID && flexSelectedUserID == currentUserID) {
  671.                     var flexSelectedTreeID = this.getFlexSelectedTreeIdFromAnchorParams();
  672.                     var flexFocusedTreeID = this.getFlexFocusedTreeIdFromAnchorParams();
  673.                     var treeIdToSelect = null;
  674.                     // First try to find the current Flex selected tree in the list            
  675.                     if(flexSelectedTreeID) {
  676.                         treeIdToSelect = flexSelectedTreeID;
  677.                     }
  678.                     // Else try to find the current Flex focused tree in the list
  679.                     else if(flexFocusedTreeID) {
  680.                         treeIdToSelect = flexFocusedTreeID;
  681.                     }
  682.                     if(treeIdToSelect) {
  683.                         var selectedTreeInList = BRO_inButtonController.getSelectedTree();
  684.                         if(!selectedTreeInList || selectedTreeInList.treeID != treeIdToSelect) {
  685.                             if(BRO_inButtonController.isTreeIdInTreeList(treeIdToSelect)) {                        
  686.                                 BRO_inButtonController.selectTree(treeIdToSelect);
  687.                             }
  688.                             // If the tree is not in the list, we refresh the list. 
  689.                             // (without alert if the user is not logged).
  690.                             else {                        
  691.                                 BRO_inButtonController.selectTree(treeIdToSelect);
  692.                                 BRO_model.skipNextRequestValidation = true;
  693.                                 BRO_model.getTreesAndCurrentUser();
  694.                             }
  695.                         }
  696.                     }
  697.                 }
  698.             }
  699.             
  700.         }else{
  701.             BRO_buttonEffectHelper.stopHelpEffects();
  702.         }
  703.         if(this.recordingMode == RECORING_MODE_ONE_BY_ONE) {
  704.             BRO_recordButtonController.refreshRecordButtonLabel(BRO_toolbar.isRecording);
  705.         }
  706.     },
  707.  
  708.     getFlexSelectedUserIdFromAnchorParams:function() {
  709.         var params = this.getCurrentUrlAnchorParams();
  710.         var selectionParam = params['N-u'];
  711.         if(selectionParam && selectionParam.indexOf('_') != -1) {
  712.             return selectionParam.split("_")[1];
  713.         }
  714.         else {
  715.             return null;
  716.         }
  717.     },    
  718.     
  719.     getFlexSelectedTreeIdFromAnchorParams:function() {
  720.         var params = this.getCurrentUrlAnchorParams();
  721.         var selectionParam = params['N-s'];
  722.         if(selectionParam && selectionParam.indexOf('_') != -1) {
  723.             return selectionParam.split("_")[1];
  724.         }
  725.         else {
  726.             return null;
  727.         }
  728.     },
  729.     
  730.     getFlexFocusedTreeIdFromAnchorParams:function() {
  731.         var params = this.getCurrentUrlAnchorParams();
  732.         var focusParam = params['N-f'];
  733.         if(focusParam && focusParam.indexOf('_') != -1) {
  734.             return focusParam.split("_")[1];
  735.         }
  736.         else {
  737.             return null;
  738.         }
  739.     },    
  740.     
  741.     getCurrentPearltreesPublicUrl:function() {
  742.         var currentUrl = BRO_browserManager.getSelectedBrowserUrl();
  743.         var pearltreesUrl = null;
  744.         // If the current tab display pearltrees
  745.         if(currentUrl && currentUrl.lastIndexOf(BRO_PUBLIC_URL) == 0) {
  746.             pearltreesUrl = currentUrl.substr(0,currentUrl.indexOf('#'));
  747.         }
  748.         
  749.         if(!pearltreesUrl) {
  750.             pearltreesUrl = BRO_PUBLIC_URL+"/";
  751.         }
  752.         
  753.         return pearltreesUrl;
  754.     },    
  755.     
  756.     getCurrentUrlAnchorParams:function() {
  757.         var currentUrl = BRO_browserManager.getSelectedBrowserUrl();
  758.         var params = [];
  759.         var paramsString = currentUrl.substr(currentUrl.indexOf('#')+1,currentUrl.length);        
  760.         if(paramsString.length==0) {
  761.             return params;
  762.         }
  763.         else if(paramsString.indexOf('&') != -1) {
  764.             var nvPairs = paramsString.split("&");
  765.             for (i = 0; i < nvPairs.length; i++) {
  766.                  var nvPair = nvPairs[i].split("=");
  767.                  var name = nvPair[0];
  768.                  var value = nvPair[1];
  769.                  params[name] = value;
  770.             }        
  771.         }
  772.         else {
  773.             var nvPair = paramsString.split("=");
  774.             var name = nvPair[0];
  775.             var value = nvPair[1];
  776.             params[name] = value;
  777.         }
  778.         return params;    
  779.     },   
  780.     
  781.     isPearltreesPublicUrl:function() {
  782.         var currentUrl = BRO_browserManager.getSelectedBrowserUrl();
  783.         // If the current tab display pearltrees
  784.         return (currentUrl.lastIndexOf(BRO_PUBLIC_URL) == 0);       
  785.     },
  786.     
  787.     showOptions: function() { 
  788.         var win = window.openDialog("chrome://broceliand/content/view/options.xul",
  789.                                       "PrefWindow", 
  790.                                       "chrome=yes," +
  791.                                       "titlebar=yes," +
  792.                                       "toolbar=yes," +
  793.                                       "centerscreen=yes," +
  794.                                       "dialog=no");        
  795.         BRO_toolbar.setOptionWindow(win);
  796.     },
  797.     setOptionWindow:function(value) {
  798.         BRO_toolbar.optionWindow = value; 
  799.     },
  800.     getOptionWindow:function() {
  801.         return BRO_toolbar.optionWindow;
  802.     },
  803.     
  804.     record: function(){
  805.         BRO_ButtonsHandler.startRecording();
  806.     },
  807.     
  808.     showLoginForm: function() {     
  809.         if(this.isRecording) {
  810.             BRO_toolbar.setRecording(false);
  811.         }
  812.         
  813.         // This page handle the main pearltrees account stuffs.
  814.         BRO_tools.openAndReuseOneTabPerURL(BRO_SERVICE_FF_URL+"login");
  815.     },
  816.     
  817.     isBrowserVersionGreaterOrEqual:function(versionToCompare) {
  818.         var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
  819.                                 .getService(Components.interfaces.nsIXULAppInfo);
  820.           var versionChecker = Components.classes["@mozilla.org/xpcom/version-comparator;1"]
  821.                                          .getService(Components.interfaces.nsIVersionComparator);        
  822.           return (versionChecker.compare(appInfo.version, versionToCompare) >= 0);
  823.     },
  824.     
  825.     isUserWantToLogin: function() {         
  826.         var args = { wantLogin: 'false' };
  827.         var dialog = window.openDialog("chrome://broceliand/content/view/popup/loginPopup.xul", 
  828.                                        "", 
  829.                                        "chrome=yes," +
  830.                                        "dialog=yes," +
  831.                                        "modal=yes," +
  832.                                        "centerscreen=yes," +
  833.                                        "resizable=no", 
  834.                                        args);
  835.         return args.wantLogin;
  836.     },
  837.     
  838.     showHelpRecording:function() {
  839.         BRO_ButtonsHandler.closeButtonPopups();
  840.         
  841.         var popupX = 50;
  842.         var popupY = 200;
  843.         var recordButton = document.getElementById('BRO_recordButton');
  844.         if(recordButton) {
  845.             popupX = recordButton.boxObject.screenX;
  846.             popupY = recordButton.boxObject.screenY + recordButton.boxObject.height;            
  847.         }        
  848.         
  849.         // @see https://developer.mozilla.org/en/DOM/window.open#Window_functionality_features
  850.         var args = {isStart:true};
  851.         var win = window.openDialog("chrome://broceliand/content/view/popup/helpPopup.xul",
  852.                 "helpStartup",   
  853.                 "all=no," +
  854.                 "titlebar=no," + 
  855.                 "chrome=yes," +
  856.                 "toolbar=no," +
  857.                 "dialog=no," +
  858.                 "resizable=no," + 
  859.                 "modal=yes," +
  860.                 "dependent=yes," +
  861.                 "top="+popupY+"px," +
  862.                 "left="+popupX+"px," +
  863.                 "width=421," +
  864.                 "height=271",
  865.                 args);
  866.         // width = image width + 39
  867.         // height = image height + 63
  868.         
  869.         BRO_toolbar.helpStartupWindow = win;
  870.     },
  871.     
  872.     showHelp:function() {
  873.         BRO_ButtonsHandler.closeButtonPopups();
  874.         
  875.         var popupX = 50;
  876.         var popupY = 200;
  877.         var recordButton = document.getElementById('BRO_recordButton');
  878.         if(recordButton) {
  879.             popupX = recordButton.boxObject.screenX;
  880.             popupY = recordButton.boxObject.screenY + recordButton.boxObject.height;            
  881.         }        
  882.         
  883.         // @see https://developer.mozilla.org/en/DOM/window.open#Window_functionality_features
  884.         var args = {isStart:false};
  885.         var win = window.openDialog("chrome://broceliand/content/view/popup/helpPopup.xul",
  886.                 "help", 
  887.                 "all=no," +
  888.                 "titlebar=no," + 
  889.                 "chrome=yes," +
  890.                 "toolbar=no," +
  891.                 "dialog=no," +
  892.                 "resizable=no," + 
  893.                 "modal=yes," +
  894.                 "dependent=yes," +
  895.                 "top="+popupY+"px," +
  896.                 "left="+popupX+"px," +
  897.                 "width=345," +
  898.                 "height=170",
  899.                 args);
  900.         // width = image width + 39
  901.         // height = image height + 63
  902.         
  903.         BRO_toolbar.helpStartupWindow = win;
  904.     },    
  905.     
  906.     showNotePopup:function() {
  907.         BRO_ButtonsHandler.closeButtonPopups();       
  908.          
  909.          var notePanel = document.getElementById('BRO_notePanel');
  910.          
  911.          // Use Panels if possible (firefox 3.0+ only).
  912.          if(this.isBrowserVersionGreaterOrEqual("3.0") && notePanel) {
  913.              var recordButton = document.getElementById('BRO_recordButton');
  914.              notePanel.openPopup(recordButton, "after_start");        
  915.          }
  916.          else{       
  917.             var popupX = 50;
  918.             var popupY = 200;
  919.             var recordButton = document.getElementById('BRO_recordButton');
  920.             if(recordButton) {
  921.                 popupX = recordButton.boxObject.screenX;
  922.                 popupY = recordButton.boxObject.screenY + recordButton.boxObject.height;            
  923.             }
  924.             
  925.             // @see https://developer.mozilla.org/en/DOM/window.open#Window_functionality_features
  926.             var args = {inn:{defaultText: BRO_noteController.getDefaultText()}, out:null};
  927.             var win = window.openDialog("chrome://broceliand/content/view/popup/notePopup.xul",
  928.                     "", 
  929.                     "all=no," +
  930.                     "titlebar=no," + 
  931.                     "chrome=yes," +
  932.                     "toolbar=no," +
  933.                     "dialog=no," +
  934.                     "resizable=no," + 
  935.                     "modal=yes," +
  936.                     "dependent=yes," +
  937.                     "top="+popupY+"px," +
  938.                     "left="+popupX+"px",
  939.                     args);   
  940.                
  941.             var params = args.out;   
  942.             if (params && params.confirm) {
  943.                 BRO_noteController.saveNoteAndRecordIfNotRecorded(params.noteText);
  944.             }
  945.          }
  946.     },
  947.      
  948.     showNameMapWindow:function() {
  949.         BRO_ButtonsHandler.closeButtonPopups();       
  950.         
  951.         var newTreePanel = document.getElementById('BRO_newTreePanel');
  952.         
  953.         // Use Panels if possible (firefox 3.0+ only).
  954.         if(this.isBrowserVersionGreaterOrEqual("3.0") && newTreePanel) {
  955.             var newButton = document.getElementById('BRO_newButton');
  956.             newTreePanel.openPopup(newButton, "after_start");
  957.         }
  958.         else {
  959.             if(BRO_toolbar.nameMapWindow && !BRO_toolbar.nameMapWindow.closed) {
  960.                 return;
  961.             }
  962.             
  963.             var popupX = 50;
  964.             var popupY = 200; 
  965.             var newButton = document.getElementById('BRO_newButton');
  966.             if(newButton) {
  967.                 popupX = newButton.boxObject.screenX;
  968.                 popupY = newButton.boxObject.screenY + newButton.boxObject.height;            
  969.             }
  970.      
  971.             // @see https://developer.mozilla.org/en/Code_snippets/Dialogs_and_Prompts#Passing_arguments_and_displaying_a_dialog
  972.             // @see https://developer.mozilla.org/en/DOM/window.open#Window_functionality_features
  973.             var args = {inn:{confirm: 'false', mapName:null}, out:null};
  974.             var win = window.openDialog("chrome://broceliand/content/view/popup/nameMapPopup.xul", 
  975.                     BRO_locale.getString('popup.nameMap.title'), 
  976.                     "titlebar=no," +
  977.                     "chrome=yes," +
  978.                     "toolbar=no," +
  979.                     "dialog=no," +
  980.                     "resizable=no," + 
  981.                     "modal=yes," +
  982.                     "dependent=yes," +
  983.                     "top="+popupY+"px," +
  984.                     "left="+popupX+"px",
  985.                     args);
  986.             
  987.             if(args.out) {
  988.                 BRO_toolbar.nameMapWindow = win;
  989.                 if (args.out && args.out.confirm) {
  990.                     BRO_inButtonController.createNewTree(args.out.mapName);
  991.                 } else {
  992.                     BRO_inButtonController._selectedNewHistory = null;
  993.                 }
  994.             }
  995.         }
  996.     },       
  997.     
  998.     showNameMapDoneWindow:function() {        
  999.         BRO_ButtonsHandler.closeButtonPopups();
  1000.         
  1001.         var popupX = 50;
  1002.         var popupY = 400; 
  1003.         var newButton = document.getElementById('BRO_newButton');
  1004.         if(newButton) {
  1005.             popupX = newButton.boxObject.screenX;
  1006.             popupY = newButton.boxObject.screenY + newButton.boxObject.height;            
  1007.         }
  1008.         
  1009.         var args = {inn:{isCurrentUrlRecorded: this.isCurrentUrlRecorded()}, out:null};
  1010.         var win = window.openDialog("chrome://broceliand/content/view/popup/nameMapDonePopup.xul", 
  1011.                 "", 
  1012.                 "titlebar=no," + 
  1013.                 "chrome=yes," +
  1014.                 "toolbar=no," +
  1015.                 "dialog=no," +
  1016.                 "resizable=no," + 
  1017.                 "modal=yes," +
  1018.                 "dependent=yes," +
  1019.                 "top="+popupY+"px," +
  1020.                 "left="+popupX+"px",
  1021.                 args);
  1022.     },    
  1023.  
  1024.     showTreeFullWindow:function() {
  1025.         BRO_ButtonsHandler.closeButtonPopups();
  1026.         
  1027.         var popupX = 50; 
  1028.         var popupY = 200;
  1029.         var recordButton = document.getElementById('BRO_recordButton');
  1030.         if(recordButton) {
  1031.             popupX = recordButton.boxObject.screenX;
  1032.             popupY = recordButton.boxObject.screenY + recordButton.boxObject.height;            
  1033.         }    
  1034.  
  1035.         var args = { createNewMap: 'false', pearlCount: BRO_toolbar.getSelectionPearlCount() };
  1036.         // @see https://developer.mozilla.org/en/DOM/window.open#Window_functionality_features
  1037.         
  1038.         var win = window.openDialog("chrome://broceliand/content/view/popup/treeFullPopup.xul", "treeFull", 
  1039.                 "titlebar=no," +
  1040.                 "chrome=yes," +
  1041.                 "toolbar=no," +
  1042.                 "dialog=no," +
  1043.                 "resizable=no," +
  1044.                 "modal=yes," +
  1045.                 "dependent=yes," + 
  1046.                 "top="+popupY+"px," +
  1047.                 "left="+popupX+"px",
  1048.                 args);    
  1049.         
  1050.         if(args.createNewMap) {
  1051.             BRO_inButtonController.showNameMapWindow(true);
  1052.         }
  1053.         else{            
  1054.             var selectedTree = BRO_inButtonController.getSelectedTree();
  1055.             var rootTree = BRO_model.getRootTree();
  1056.             if(selectedTree && selectedTree.treeID == rootTree.treeID && selectedTree.pearlCount >= MAX_PEARLS_IN_TREE) {
  1057.                 BRO_inButtonController.selectDropZoneTree();
  1058.             }
  1059.         }
  1060.     },
  1061.     
  1062.     showManyPearlsWindow:function() {
  1063.         BRO_ButtonsHandler.closeButtonPopups();
  1064.         
  1065.         var popupX = 50;
  1066.         var popupY = 200;
  1067.         var recordButton = document.getElementById('BRO_recordButton');
  1068.         if(recordButton) {
  1069.             popupX = recordButton.boxObject.screenX;
  1070.             popupY = recordButton.boxObject.screenY + recordButton.boxObject.height;            
  1071.         }
  1072.         
  1073.         var args = { createNewMap: 'false', pearlCount: BRO_toolbar.getSelectionPearlCount() };
  1074.         // @see https://developer.mozilla.org/en/DOM/window.open#Window_functionality_features
  1075.         var win = window.openDialog("chrome://broceliand/content/view/popup/manyPearlsPopup.xul", "manyPearls", 
  1076.                 "titlebar=no," +
  1077.                 "chrome=yes," +
  1078.                 "toolbar=no," +
  1079.                 "dialog=no," +
  1080.                 "resizable=no," +
  1081.                 "modal=yes," +
  1082.                 "dependent=yes," +
  1083.                 "top="+popupY+"px," +
  1084.                 "left="+popupX+"px",
  1085.                 args);
  1086.         
  1087.         BRO_toolbar.manyPearlsWindow = win;
  1088.         
  1089.         if(args.createNewMap) {
  1090.             BRO_inButtonController.showNameMapWindow();
  1091.         }    
  1092.     },
  1093.     
  1094.     showTreeDeletedMessage: function() {
  1095.         // Stop recording effect
  1096.         if(this.isRecording) { 
  1097.             BRO_toolbar.setRecording(false) 
  1098.         };
  1099.         // Refresh tree list
  1100.         BRO_inButtonController.selectRootTree();
  1101.         BRO_model.getTreesAndCurrentUser();
  1102.         
  1103.         // Show message
  1104.         BRO_log.log("Can't continue this history. Tree has been deleted");
  1105.         BRO_log.info(BRO_locale.getString('popup.error.treeDeleted')); 
  1106.     },
  1107.     
  1108.     errorOnContinueHistory: function(errorCode) {
  1109.         // Stop recording effect
  1110.         if(this.isRecording) { 
  1111.             BRO_toolbar.setRecording(false) 
  1112.         };
  1113.         // Refresh tree list
  1114.         BRO_model.getTreesAndCurrentUser();
  1115.         
  1116.         // Show message
  1117.         BRO_log.log("Can't continue this history. Server error: "+errorCode);        
  1118.     },
  1119.     
  1120.     onOnline:function() {
  1121.         BRO_toolbar.isOnline = true;
  1122.         var recordButton = document.getElementById("BRO_recordButton");
  1123.         var newButton = document.getElementById("BRO_newButton");
  1124.         if(recordButton) recordButton.disabled = false;
  1125.         if(newButton) newButton.disabled = false;
  1126.     },
  1127.     
  1128.     onOffline:function() {
  1129.         BRO_toolbar.isOnline = false;
  1130.         var recordButton = document.getElementById("BRO_recordButton");
  1131.         var newButton = document.getElementById("BRO_newButton");        
  1132.         if(recordButton) recordButton.disabled = true;
  1133.         if(newButton) newButton.disabled = true;
  1134.     },
  1135.     
  1136.     /**
  1137.      * Because our extension must be used in certain environements.
  1138.      */
  1139.     validateEnv:function() {
  1140.         
  1141.         return; // No more environment validation
  1142.         
  1143.         // Check plateform
  1144.         //BRO_log.log('Platform: ---------------------------');
  1145.         var platform = navigator.platform;
  1146.         var platformVersion = window.navigator.oscpu;
  1147.                               
  1148.         //BRO_log.log('OS: '+platform+' ('+platformVersion+') / Firefox:'+appInfo.version);
  1149.         // Windows XP
  1150.         if(platformVersion == 'Windows NT 5.1') {
  1151.             var minVersion = "2";
  1152.             if(versionChecker.compare(appInfo.version, minVersion) < 0) {
  1153.                 BRO_log.warning("Pearltrees plugin currently does not fully support your firefox version.\n"+
  1154.                                 "On Windows XP we only support firefox "+minVersion+" "+
  1155.                                 "and you are running firefox "+appInfo.version+"\n"+
  1156.                                 "Contact the pearltrees team for more info.");
  1157.             }  
  1158.         }
  1159.         // Windows Vista
  1160.         else if(platformVersion == 'Windows NT 6.0'){
  1161.             var minVersion = "2";
  1162.             if(versionChecker.compare(appInfo.version, minVersion) < 0) {
  1163.                 BRO_log.warning("Pearltrees plugin currently does not fully support your firefox version.\n"+
  1164.                                 "On Windows Vista we only support firefox "+minVersion+" "+
  1165.                                 "and you are running firefox "+appInfo.version+"\n"+
  1166.                                 "Contact the pearltrees team for more info.");
  1167.             }           
  1168.         }
  1169.         // Mac
  1170.         else if(platform == 'MacPPC' || platform == 'MacIntel') {
  1171.             var minVersion = "3";
  1172.             if(versionChecker.compare(appInfo.version, minVersion) < 0) {
  1173.                 BRO_log.warning("Pearltrees plugin currently does not fully support your firefox version.\n"+
  1174.                                 "On Mac we only support firefox "+minVersion+" "+
  1175.                                 "and you are running firefox "+appInfo.version+"\n"+
  1176.                                 "Contact the pearltrees team for more info.");
  1177.             }           
  1178.         }
  1179.         // Linux
  1180.         else if(platform == 'Linux i686' || platform == 'Linux x86_64' || platform == 'Linux i686 (x86_64)'){
  1181.             var minVersion = "3";
  1182.             if(versionChecker.compare(appInfo.version, minVersion) < 0) {
  1183.                 BRO_log.warning("Pearltrees plugin currently does not fully support your firefox version.\n"+
  1184.                                 "On Linux we only support firefox "+minVersion+" "+
  1185.                                 "and you are running firefox "+appInfo.version+"\n"+
  1186.                                 "Contact the pearltrees team for more info.");
  1187.             }
  1188.         }
  1189.         // Others
  1190.         else {
  1191.             BRO_log.error("Pearltrees plugin currently does not fully support your operating system: "+platform+".");
  1192.         }
  1193.         
  1194.         // Check plugins
  1195.         //BRO_log.log('Plugins: ----------------------------');
  1196.         var plugins = navigator.plugins;
  1197.         for(var i=0; i<plugins.length; i++) {
  1198.             var name = plugins[i].name;
  1199.             //BRO_log.log(name);
  1200.         }
  1201.         //BRO_log.log(plugins.length+' plugins registered');
  1202.         
  1203.         // Check extensions, we use here FUEL, created in firefox 3
  1204.         //BRO_log.log('Extensions: ----------------------------');
  1205.         if(typeof(Application) != 'undefined') {
  1206.             var extensions = Application.extensions.all;
  1207.             for(var i=0; i<extensions.length; i++) {
  1208.                 var ext = extensions[i];
  1209.                 if(!ext.enabled) continue;
  1210.             }
  1211.         }
  1212.     },
  1213.     
  1214.     // @see https://developer.mozilla.org/en/Code_snippets/Interaction_between_privileged_and_non-privileged_pages
  1215.     handleFlexCommand: function(event) {
  1216.         if(!this.isPearltreesPublicUrl()) {
  1217.             return;
  1218.         }
  1219.         
  1220.         var commandName = event.target.getAttribute("commandName");
  1221.         
  1222.         if(commandName == "login") {
  1223.             if(this.isFirstInstallMode) {
  1224.                 this.setFirstInstallMode(false);
  1225.             }
  1226.             BRO_model.getTreesAndCurrentUser();
  1227.         }
  1228.         else if(commandName == "logout") {            
  1229.             BRO_model.resetModel();
  1230.         }
  1231.         else if(commandName == "detectPearlbar") {            
  1232.             var mainWindowDocument = content.document;
  1233.             
  1234.             var element = mainWindowDocument.createElement("pearlbarCommandEvent");
  1235.             element.setAttribute("commandName", "pearlbarIsInstalled");
  1236.             mainWindowDocument.documentElement.appendChild(element);            
  1237.             
  1238.             var event = mainWindowDocument.createEvent("Events");
  1239.             event.initEvent("pearlbarCommandEvent", true, false);
  1240.             element.dispatchEvent(event);
  1241.         }
  1242.     },
  1243.     
  1244.     getMainWindowDocument:function() {
  1245.         return window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
  1246.            .getInterface(Components.interfaces.nsIWebNavigation)
  1247.            .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
  1248.            .rootTreeItem
  1249.            .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
  1250.            .getInterface(Components.interfaces.nsIDOMWindow)
  1251.            .document;
  1252.     },
  1253.     
  1254.     initFlexCommandListener:function () {
  1255.         var mainWindowDocument = this.getMainWindowDocument();
  1256.         mainWindowDocument.addEventListener("flexCommandEvent", function(e) { BRO_toolbar.handleFlexCommand(e); }, false, true);        
  1257.     }
  1258. };
  1259. BRO_toolbar.init();
  1260.  
  1261.